import tkinter as tk
from tkinter import messagebox, filedialog, Menu, ttk
import os
import json
from PIL import Image, ImageTk
import base64
import openai
import uuid
import mysql.connector
from mysql.connector import Error
from PIL import ImageTk
import io

# 数据库配置
DB_CONFIG = {
    'host': 'localhost',
    'user': 'root',
    'password': '密码',
    'database': 'invoice_system'
}

# # 设置环境变量（保持不变）
# tcl_library_path = r"D:\python\Lib\tkinter"
# os.environ['TCL_LIBRARY'] = tcl_library_path

# 存储用户数据的文件路径（保持不变）
USER_DATA_FILE = r"D:\python\python -xiazai\news\user_data.json"


# 加载用户数据（保持不变）
def load_user_data():
    if os.path.exists(USER_DATA_FILE):
        with open(USER_DATA_FILE, 'r') as file:
            return json.load(file)
    else:
        return {}


# 保存用户数据（保持不变）
def save_user_data(user_data):
    with open(USER_DATA_FILE, 'w') as file:
        json.dump(user_data, file)

class BaseInterface:
    def __init__(self, master, prev_interface=None):
        self.master = master
        self.prev_interface = prev_interface

    def show(self):
        self.master.deiconify()

    def hide(self):
        self.master.withdraw()


# 模拟数据库，从文件加载数据（保持不变）
user_database = load_user_data()


# 主界面类（保持不变）
class MainInterface(BaseInterface):
    def __init__(self, master):
        super().__init__(master)
        self.master.title("发票管理系统")
        self.master.geometry("400x300")

        # 显示发票管理系统标题
        self.title_label = tk.Label(self.master, text="发票管理系统", font=("Arial", 16))
        self.title_label.pack(pady=50)

        # 登录按钮
        self.login_button = tk.Button(self.master, text="登录", command=self.open_login_window)
        self.login_button.pack(side=tk.LEFT, padx=50)

        # 注册按钮
        self.register_button = tk.Button(self.master, text="注册", command=self.open_register_window)
        self.register_button.pack(side=tk.RIGHT, padx=50)

    def open_login_window(self):
        new_window = tk.Toplevel(self.master)
        login_interface = LoginInterface(new_window, self)
        self.hide()
        return login_interface

    def open_register_window(self):
        new_window = tk.Toplevel(self.master)
        register_interface = RegisterInterface(new_window, self)
        self.hide()
        return register_interface

    def show(self):
        super().show()


# 登录界面类（保持不变）
class LoginInterface(BaseInterface):
    def __init__(self, master, prev_interface):
        super().__init__(master, prev_interface)
        self.master.title("登录")
        self.master.geometry("400x300")

        # 账号标签和输入框
        self.account_label = tk.Label(self.master, text="账号")
        self.account_label.pack()
        self.account_entry = tk.Entry(self.master)
        self.account_entry.pack()

        # 密码标签和输入框
        self.password_label = tk.Label(self.master, text="密码")
        self.password_label.pack()
        self.password_entry = tk.Entry(self.master, show="*")
        self.password_entry.pack()

        # 确认按钮
        self.confirm_button = tk.Button(self.master, text="确认", command=self.login_verify)
        self.confirm_button.pack(side=tk.LEFT, padx=50)

        # 返回按钮
        self.back_button = tk.Button(self.master, text="返回", command=self.go_back)
        self.back_button.pack(side=tk.RIGHT, padx=50)

    def login_verify(self):
        account = self.account_entry.get()
        password = self.password_entry.get()
        if account in user_database and user_database[account] == password:
            new_window = tk.Toplevel(self.master)
            next_interface = NextInterface(new_window, self)
            self.hide()
            return next_interface
        else:
            messagebox.showerror("登录失败", "账号或密码错误")

    def go_back(self):
        self.prev_interface.show()
        self.master.destroy()


# 注册界面类（保持不变）
class RegisterInterface(BaseInterface):
    def __init__(self, master, prev_interface):
        super().__init__(master, prev_interface)
        self.master.title("注册")
        self.master.geometry("400x300")

        self.account_label = tk.Label(self.master, text="账号")
        self.account_label.pack()
        self.account_entry = tk.Entry(self.master)
        self.account_entry.pack()

        self.password_label = tk.Label(self.master, text="密码")
        self.password_label.pack()
        self.password_entry = tk.Entry(self.master, show="*")
        self.password_entry.pack()

        self.confirm_button = tk.Button(self.master, text="确认", command=self.register_user)
        self.confirm_button.pack(side=tk.LEFT, padx=50)

        self.back_button = tk.Button(self.master, text="返回", command=self.go_back)
        self.back_button.pack(side=tk.RIGHT, padx=50)

    def register_user(self):
        account = self.account_entry.get()
        password = self.password_entry.get()
        if account and password:
            if account in user_database:
                messagebox.showerror("注册失败", "该账号已存在")
            else:
                user_database[account] = password
                save_user_data(user_database)  # 保存用户数据到文件
                messagebox.showinfo("注册成功", "注册成功，请登录")
                self.go_back()
        else:
            messagebox.showerror("注册失败", "请输入账号和密码")

    def go_back(self):
        self.prev_interface.show()
        self.master.destroy()


# 确认后的下一个界面类（保持不变）
class NextInterface(BaseInterface):
    def __init__(self, master, prev_interface):
        super().__init__(master, prev_interface)
        self.master.title("操作界面")
        self.master.geometry("455x300")

        # 查询按钮
        self.query_button = tk.Button(self.master, text="查询", command=self.open_query_window)
        self.query_button.pack(side=tk.LEFT, padx=50)

        # 上传按钮
        self.upload_button = tk.Button(self.master, text="上传", command=self.open_upload_window)
        self.upload_button.pack(side=tk.LEFT, padx=50)

        # 数据库按钮
        self.database_button = tk.Button(
            self.master,
            text="数据库",
            command=self.open_database_table
        )
        self.database_button.pack(side=tk.LEFT, padx=50)

        # 返回按钮
        self.back_button = tk.Button(self.master, text="返回", command=self.go_back)
        self.back_button.pack(side=tk.BOTTOM, pady=50)

    def open_query_window(self):
        """打开查询窗口"""
        query_window = tk.Toplevel(self.master)
        query_window.title("查询发票")
        query_window.geometry("400x400")
        query_window.resizable(False, False)

        # 创建查询框架
        query_frame = tk.Frame(query_window, padx=20, pady=20)
        query_frame.pack(fill=tk.BOTH, expand=True)

        # 发票编号查询
        tk.Label(query_frame, text="发票编号:").grid(row=0, column=0, sticky=tk.W, pady=5)
        invoice_number_entry = tk.Entry(query_frame)
        invoice_number_entry.grid(row=0, column=1, sticky=tk.EW, pady=5)

        # 日期范围查询
        tk.Label(query_frame, text="开始日期:").grid(row=1, column=0, sticky=tk.W, pady=5)
        start_date_entry = tk.Entry(query_frame)
        start_date_entry.grid(row=1, column=1, sticky=tk.EW, pady=5)
        tk.Label(query_frame, text="(格式: YYYY-MM-DD)").grid(row=1, column=2, sticky=tk.W, pady=5)

        tk.Label(query_frame, text="结束日期:").grid(row=2, column=0, sticky=tk.W, pady=5)
        end_date_entry = tk.Entry(query_frame)
        end_date_entry.grid(row=2, column=1, sticky=tk.EW, pady=5)
        tk.Label(query_frame, text="(格式: YYYY-MM-DD)").grid(row=2, column=2, sticky=tk.W, pady=5)

        # 创建统计结果显示区域
        stats_frame = tk.Frame(query_frame)
        stats_frame.grid(row=3, column=0, columnspan=3, pady=10)
        
        # 统计结果标签
        stats_label = tk.Label(stats_frame, text="统计结果：", font=("微软雅黑", 10, "bold"))
        stats_label.pack(side=tk.LEFT, padx=5)
        
        # 发票数量标签
        count_label = tk.Label(stats_frame, text="发票数量：0张")
        count_label.pack(side=tk.LEFT, padx=5)
        
        # 总金额标签
        amount_label = tk.Label(stats_frame, text="总金额：0元")
        amount_label.pack(side=tk.LEFT, padx=5)

        def extract_amount(text):
            """从文本中提取所有金额并计算总和"""
            if not text:
                return 0.0
            
            total = 0.0
            # 查找"金额合计"部分
            if "金额合计" in text:
                # 分割文本，获取金额合计部分
                parts = text.split("金额合计")
                if len(parts) > 1:
                    amount_text = parts[1].strip()
                    # 查找所有金额
                    lines = amount_text.split('\n')
                    for line in lines:
                        line = line.strip()
                        # 去掉开头的"-"字符
                        if line.startswith('-'):
                            line = line[1:].strip()
                        # 提取所有数字（包括小数点）
                        amount_str = ''.join(c for c in line if c.isdigit() or c == '.')
                        if amount_str:  # 如果提取到了数字
                            try:
                                amount = float(amount_str)
                                total += amount
                                print(f"提取到金额: {amount}")
                            except ValueError:
                                print(f"无法转换金额: {amount_str}")
            
            print(f"最终总金额: {total}")  # 调试信息
            return total

        # 查询按钮
        def perform_query():
            invoice_number = invoice_number_entry.get().strip()
            start_date = start_date_entry.get().strip()
            end_date = end_date_entry.get().strip()

            # 构建查询条件
            conditions = []
            params = []
            
            if invoice_number:
                conditions.append("invoice_number LIKE %s")
                params.append(f"%{invoice_number}%")
            
            if start_date:
                conditions.append("issue_date >= %s")
                params.append(start_date)
            
            if end_date:
                conditions.append("issue_date <= %s")
                params.append(end_date)

            # 执行查询
            try:
                conn = mysql.connector.connect(**DB_CONFIG)
                cursor = conn.cursor()

                # 构建SQL查询
                sql = "SELECT id, invoice_number, issue_date, total_amount, recognition_text FROM invoices"
                if conditions:
                    sql += " WHERE " + " AND ".join(conditions)
                sql += " ORDER BY created_time DESC"

                cursor.execute(sql, params)
                rows = cursor.fetchall()

                # 更新统计信息
                total_amount = 0
                for row in rows:
                    # 使用recognition_text来提取金额
                    amount = extract_amount(row[4])  # 使用recognition_text字段
                    total_amount += amount
                    print(f"发票 {row[1]} 金额: {amount}")  # 调试信息

                # 更新统计标签
                count_label.config(text=f"发票数量：{len(rows)}张")
                amount_label.config(text=f"总金额：{total_amount:.2f}元")

                # 创建结果窗口
                result_window = tk.Toplevel(query_window)
                result_window.title("查询结果")
                result_window.geometry("800x400")
                result_window.resizable(True, True)

                # 创建表格
                tree = ttk.Treeview(
                    result_window,
                    columns=("唯一标识符", "发票编号", "开票日期", "操作"),
                    show="headings",
                    height=10
                )
                tree.heading("唯一标识符", text="唯一标识符")
                tree.heading("发票编号", text="发票编号")
                tree.heading("开票日期", text="开票日期")
                tree.heading("操作", text="操作")
                tree.pack(pady=20, padx=10, fill=tk.BOTH, expand=True)

                scrollbar = ttk.Scrollbar(tree, orient="vertical", command=tree.yview)
                tree.configure(yscrollcommand=scrollbar.set)
                scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

                # 显示结果
                for row in rows:
                    item = tree.insert("", tk.END, values=(row[0], row[1], row[2], "查看/删除"))
                    # 绑定双击事件
                    tree.bind("<Double-1>", lambda e: self.show_image(tree, e))
                    # 绑定右键菜单
                    tree.bind("<Button-3>", lambda e: self.show_context_menu(tree, e))

                if not rows:
                    messagebox.showinfo("查询结果", "未找到匹配的记录")

            except Error as e:
                messagebox.showerror("数据库错误", f"查询失败: {str(e)}")
            finally:
                if 'conn' in locals() and conn.is_connected():
                    cursor.close()
                    conn.close()

        # 添加查询按钮
        query_button = tk.Button(
            query_frame,
            text="查询",
            command=perform_query
        )
        query_button.grid(row=4, column=0, columnspan=3, pady=20)

        # 添加清除按钮
        def clear_entries():
            invoice_number_entry.delete(0, tk.END)
            start_date_entry.delete(0, tk.END)
            end_date_entry.delete(0, tk.END)
            count_label.config(text="发票数量：0张")
            amount_label.config(text="总金额：0元")

        clear_button = tk.Button(
            query_frame,
            text="清除",
            command=clear_entries
        )
        clear_button.grid(row=4, column=1, columnspan=3, pady=20)

        # 设置列权重
        query_frame.columnconfigure(1, weight=1)

    def open_database_table(self):
        """从数据库获取数据并显示表格"""
        db_window = tk.Toplevel(self.master)
        db_window.title("发票数据库")
        db_window.geometry("800x400")
        db_window.resizable(True, True)

        # 创建表格
        tree = ttk.Treeview(
            db_window,
            columns=("唯一标识符", "发票编号", "开票日期", "操作"),
            show="headings",
            height=10
        )
        tree.heading("唯一标识符", text="唯一标识符")
        tree.heading("发票编号", text="发票编号")
        tree.heading("开票日期", text="开票日期")
        tree.heading("操作", text="操作")
        tree.pack(pady=20, padx=10, fill=tk.BOTH, expand=True)

        scrollbar = ttk.Scrollbar(tree, orient="vertical", command=tree.yview)
        tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 从数据库查询数据
        try:
            conn = mysql.connector.connect(**DB_CONFIG)
            cursor = conn.cursor()
            cursor.execute("SELECT id, invoice_number, issue_date FROM invoices ORDER BY created_time DESC")
            rows = cursor.fetchall()

            for row in rows:
                item = tree.insert("", tk.END, values=(*row, "查看/删除"))
                # 绑定双击事件
                tree.bind("<Double-1>", lambda e: self.show_image(tree, e))
                # 绑定右键菜单
                tree.bind("<Button-3>", lambda e: self.show_context_menu(tree, e))

        except Error as e:
            messagebox.showerror("数据库错误", f"获取数据失败: {str(e)}")
        finally:
            if 'conn' in locals() and conn.is_connected():
                cursor.close()
                conn.close()

    def show_context_menu(self, tree, event):
        """显示右键菜单"""
        # 获取点击的项目
        item = tree.identify_row(event.y)
        if not item:
            return

        # 选中该项目
        tree.selection_set(item)
        
        # 创建右键菜单
        context_menu = Menu(tree, tearoff=0)
        context_menu.add_command(label="查看图片", command=lambda: self.show_image(tree, None))
        context_menu.add_command(label="删除记录", command=lambda: self.delete_record(tree, item))
        
        # 显示菜单
        context_menu.post(event.x_root, event.y_root)

    def delete_record(self, tree, item):
        """删除选中的记录"""
        # 获取选中项的值
        values = tree.item(item)['values']
        invoice_id = values[0]
        
        # 确认删除
        if not messagebox.askyesno("确认删除", f"确定要删除发票编号为 {values[1]} 的记录吗？"):
            return
        
        try:
            conn = mysql.connector.connect(**DB_CONFIG)
            cursor = conn.cursor()
            
            # 删除记录
            cursor.execute("DELETE FROM invoices WHERE id = %s", (invoice_id,))
            conn.commit()
            
            # 从树形视图中移除
            tree.delete(item)
            
            messagebox.showinfo("成功", "记录已删除")
            
        except Error as e:
            messagebox.showerror("数据库错误", f"删除失败: {str(e)}")
        finally:
            if 'conn' in locals() and conn.is_connected():
                cursor.close()
                conn.close()

    def show_image(self, tree, event):
        """显示选中记录的图片和识别结果"""
        # 获取选中的项目
        selection = tree.selection()
        if not selection:
            return
            
        item = selection[0]
        invoice_id = tree.item(item)['values'][0]
        
        try:
            conn = mysql.connector.connect(**DB_CONFIG)
            cursor = conn.cursor()
            # 修改SQL查询以获取图片数据和识别结果
            cursor.execute("""
                SELECT image_data, invoice_number, issue_date, 
                       buyer_info, seller_info, goods_info, total_amount,
                       recognition_text
                FROM invoices WHERE id = %s
            """, (invoice_id,))
            result = cursor.fetchone()
            
            if result and result[0]:
                # 创建新窗口显示图片和文字
                image_window = tk.Toplevel(self.master)
                image_window.title("发票图片和识别结果")
                image_window.geometry("1200x600")
                
                # 创建左右分栏
                left_frame = tk.Frame(image_window)
                left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10)
                
                right_frame = tk.Frame(image_window)
                right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=10, pady=10)
                
                # 左侧显示图片
                image_data = result[0]
                image = Image.open(io.BytesIO(image_data))
                image.thumbnail((580, 580))
                photo = ImageTk.PhotoImage(image)
                
                image_label = tk.Label(left_frame, image=photo)
                image_label.image = photo
                image_label.pack(padx=10, pady=10)
                
                # 右侧显示识别结果
                text_frame = tk.Frame(right_frame)
                text_frame.pack(fill=tk.BOTH, expand=True)
                
                # 创建标题
                title_label = tk.Label(text_frame, text="识别结果", font=("微软雅黑", 14, "bold"))
                title_label.pack(pady=10)
                
                # 创建文本显示区域
                text_widget = tk.Text(text_frame, wrap=tk.WORD, font=("微软雅黑", 10))
                text_widget.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
                
                # 插入原始识别文本
                if result[7]:  # recognition_text
                    text_widget.insert(tk.END, "原始识别文本：\n")
                    text_widget.insert(tk.END, result[7] + "\n\n")
                    text_widget.insert(tk.END, "提取的关键信息：\n")
                
                # 插入提取的关键信息
                text_widget.insert(tk.END, f"发票编号：{result[1]}\n")
                text_widget.insert(tk.END, f"开票日期：{result[2]}\n")
                text_widget.insert(tk.END, f"购买方信息：{result[3]}\n")
                text_widget.insert(tk.END, f"销售方信息：{result[4]}\n")
                text_widget.insert(tk.END, f"商品信息：{result[5]}\n")
                text_widget.insert(tk.END, f"金额合计：{result[6]}\n")
                
                # 设置文本为只读
                text_widget.config(state=tk.DISABLED)
                
        except Error as e:
            messagebox.showerror("数据库错误", f"获取图片失败: {str(e)}")
        finally:
            if 'conn' in locals() and conn.is_connected():
                cursor.close()
                conn.close()

    def open_upload_window(self):
        new_window = tk.Toplevel(self.master)
        upload_interface = UploadInterface(new_window, self)
        self.hide()

    def go_back(self):
        self.prev_interface.show()
        self.master.destroy()


def convert_chinese_date(date_str):
    """将中文日期格式转换为MySQL日期格式"""
    try:
        # 移除可能的空格
        date_str = date_str.strip()
        
        # 如果日期为空，返回None
        if not date_str:
            return None
            
        # 替换中文年月日为数字
        date_str = date_str.replace('年', '-').replace('月', '-').replace('日', '')
        
        # 分割日期
        year, month, day = date_str.split('-')
        
        # 确保月份和日期是两位数
        month = month.zfill(2)
        day = day.zfill(2)
        
        # 组合成MySQL日期格式
        return f"{year}-{month}-{day}"
    except Exception as e:
        print(f"日期转换错误: {str(e)}")
        return None


# 上传界面类（关键修改部分）
class UploadInterface(BaseInterface):
    def __init__(self, master, prev_interface):
        super().__init__(master, prev_interface)
        self.master.title("上传界面")
        self.master.geometry("400x300")

        self.upload_frame = tk.Frame(self.master)
        self.upload_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)

        self.upload_button = tk.Button(self.upload_frame, text="选择图片", command=self.upload_image)
        self.upload_button.pack(pady=20)

        self.image_container = tk.Frame(self.upload_frame)
        self.image_container.pack(pady=10)

        self.confirm_button = tk.Button(self.upload_frame, text="确认", command=self.show_confirmation_dialog)
        self.confirm_button.pack(side=tk.LEFT, padx=20, pady=20)

        self.back_button = tk.Button(self.upload_frame, text="返回", command=self.go_back)
        self.back_button.pack(side=tk.RIGHT, padx=20, pady=20)

        self.images = []  # 存储 (文件路径, 原始图片对象) 元组
        self.thumbnails = []  # 存储缩略图对象
        self.image_labels = []  # 存储显示的图片标签
        self.current_image_index = None  # 当前选中的图片索引

        # 创建右键菜单
        self.context_menu = Menu(self.master, tearoff=0)
        self.context_menu.add_command(label="删除照片", command=self.delete_selected_image)

    def upload_image(self):
        file_path = filedialog.askopenfilename(filetypes=[("图片文件", "*.jpg;*.jpeg;*.png")])
        if file_path:
            # 打开原始图片
            original_img = Image.open(file_path)

            # 保存文件路径和原始图片对象（修改此处）
            self.images.append((file_path, original_img))

            # 创建缩略图
            thumbnail = original_img.copy()
            thumbnail.thumbnail((200, 200))
            photo = ImageTk.PhotoImage(thumbnail)
            self.thumbnails.append(photo)

            # 创建图片标签
            label = tk.Label(self.image_container, image=photo)
            label.image = photo
            label.pack(pady=10)
            self.image_labels.append(label)

            # 绑定点击事件 - 左键点击放大
            label.bind("<Button-1>", lambda e, idx=len(self.image_labels) - 1: self.show_image_fullscreen(idx))

            # 绑定右键菜单
            label.bind("<Button-3>", lambda e, idx=len(self.image_labels) - 1: self.show_context_menu(e, idx))

    def show_image_fullscreen(self, index):
        """显示图片全屏预览"""
        self.current_image_index = index

        # 创建全屏窗口
        fullscreen_window = tk.Toplevel(self.master)
        fullscreen_window.title("图片预览")
        fullscreen_window.attributes('-fullscreen', True)

        # 获取屏幕尺寸
        screen_width = fullscreen_window.winfo_screenwidth()
        screen_height = fullscreen_window.winfo_screenheight()

        # 调整图片大小以适应屏幕
        img = self.images[index][1].copy()  # 从元组中取图片对象
        img.thumbnail((screen_width * 0.9, screen_height * 0.9))
        photo = ImageTk.PhotoImage(img)

        # 创建图片标签
        image_label = tk.Label(fullscreen_window, image=photo, bg="black")
        image_label.image = photo
        image_label.pack(fill=tk.BOTH, expand=True)

        # 创建关闭按钮
        close_button = tk.Button(fullscreen_window, text="×", font=("Arial", 20),
                                 bg="black", fg="white", bd=0,
                                 command=fullscreen_window.destroy)
        close_button.place(relx=0.98, rely=0.02, anchor="ne")

        # 点击窗口任何位置关闭全屏
        fullscreen_window.bind("<Button-1>", lambda e: fullscreen_window.destroy())

    def show_context_menu(self, event, index):
        """显示右键菜单"""
        self.current_image_index = index
        self.context_menu.post(event.x_root, event.y_root)

    def delete_selected_image(self):
        """删除选中的图片"""
        if self.current_image_index is not None and 0 <= self.current_image_index < len(self.image_labels):
            # 移除图片
            self.image_labels[self.current_image_index].destroy()
            del self.images[self.current_image_index]
            del self.thumbnails[self.current_image_index]
            del self.image_labels[self.current_image_index]

            # 更新剩余图片的索引绑定
            for i, label in enumerate(self.image_labels):
                label.unbind("<Button-1>")
                label.unbind("<Button-3>")
                label.bind("<Button-1>", lambda e, idx=i: self.show_image_fullscreen(idx))
                label.bind("<Button-3>", lambda e, idx=i: self.show_context_menu(e, idx))

            self.current_image_index = None

    def show_confirmation_dialog(self):
        """显示确认对话框"""
        if not self.images:
            messagebox.showerror("错误", "请先选择图片")
            return

        # 创建对话框
        dialog = tk.Toplevel(self.master)
        dialog.title("确认")
        dialog.geometry("300x150")
        dialog.configure(bg="#f0f0f0")  # 浅灰色背景
        dialog.resizable(False, False)

        # 居中显示
        dialog.update_idletasks()
        width = dialog.winfo_width()
        height = dialog.winfo_height()
        x = (self.master.winfo_width() // 2) - (width // 2) + self.master.winfo_x()
        y = (self.master.winfo_height() // 2) - (height // 2) + self.master.winfo_y()
        dialog.geometry(f"+{x}+{y}")

        # 添加内容
        message_label = tk.Label(dialog, text="是否识别？", font=("微软雅黑", 14), bg="#f0f0f0")
        message_label.pack(pady=30)

        button = tk.Button(dialog, text="确认识别", font=("微软雅黑", 12),
                           bg="white", fg="black", relief=tk.RAISED,
                           command=lambda: [dialog.destroy(), self.start_recognition()])
        button.pack(pady=10)

        # 禁止点击其他区域
        dialog.transient(self.master)
        dialog.grab_set()
        self.master.wait_window(dialog)

    def start_recognition(self):
        if not self.images:
            messagebox.showerror("错误", "未选择图片")
            return
        image_path = self.images[0][0]

        openai.api_key = #这里获取一下大模型ai的api_key
        if not openai.api_key:
            messagebox.showerror("错误", "未设置有效的API Key")
            return

        # 读取图片并转换为Base64格式
        with open(image_path, "rb") as f:
            image_data = f.read()
        image_base64 = base64.b64encode(image_data).decode('utf-8')
        image_data_uri = f"data:image/jpeg;base64,{image_base64}"

        prompt = """请识别以下发票图片中的关键信息：发票编号、开票日期、购买方信息、销售方信息、商品名称、金额合计"""

        try:
            client = openai.OpenAI(
                base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
                api_key=openai.api_key
            )

            response = client.chat.completions.create(
                model="qwen-vl-max",
                messages=[
                    {
                        "role": "user",
                        "content": [
                            {"type": "text", "text": prompt},
                            {"type": "image_url", "image_url": {"url": image_data_uri}}
                        ]
                    }
                ],
                temperature=0.2,
                top_p=0.8
            )

            if response.choices and response.choices[0].message.content:
                self.show_recognition_result(response.choices[0].message.content)
            else:
                messagebox.showerror("错误", "模型返回空结果")

        except openai.APIError as e:
            messagebox.showerror("API错误", f"状态码: {e.status_code}, 错误信息: {e.error.message}")
        except Exception as e:
            messagebox.showerror("系统错误", f"调用失败: {str(e)}")

    def show_recognition_result(self, result_text):
        """显示识别结果并保存文本"""
        self.result_window = tk.Toplevel(self.master)
        self.result_window.title("识别结果")
        self.result_window.geometry("600x400")
        self.result_window.configure(bg="#f0f0f0")

        self.result_text_widget = tk.Text(self.result_window, wrap=tk.WORD, font=("微软雅黑", 10))
        self.result_text_widget.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        self.result_text_widget.insert(tk.END, result_text)
        self.result_text_widget.config(state=tk.DISABLED)

        button_frame = tk.Frame(self.result_window, bg="#f0f0f0")
        button_frame.pack(side=tk.BOTTOM, pady=10)

        upload_button = tk.Button(button_frame, text="上传到数据库", font=("微软雅黑", 10),
                                  command=self.generate_uuid_and_upload)
        upload_button.pack(side=tk.LEFT, padx=10)

    def generate_uuid_and_upload(self):
        """生成UUID并将数据存入数据库"""
        if not hasattr(self, 'result_text_widget'):
            messagebox.showerror("错误", "识别结果未加载")
            return

        try:
            # 生成UUID
            image_uuid = str(uuid.uuid4())
            result_text = self.result_text_widget.get(1.0, tk.END).strip()
            
            # 提取关键信息
            invoice_number = self.extract_info(result_text, "发票编号")
            issue_date = self.extract_info(result_text, "开票日期")
            buyer_info = self.extract_info(result_text, "购买方信息")
            seller_info = self.extract_info(result_text, "销售方信息")
            goods_info = self.extract_info(result_text, "商品名称")
            total_amount = self.extract_info(result_text, "金额合计")

            # 转换日期格式
            mysql_date = convert_chinese_date(issue_date)
            if not mysql_date:
                messagebox.showerror("错误", "日期格式转换失败")
                return

            # 打印调试信息
            print(f"准备上传数据：")
            print(f"UUID: {image_uuid}")
            print(f"发票编号: {invoice_number}")
            print(f"原始日期: {issue_date}")
            print(f"转换后日期: {mysql_date}")
            print(f"购买方: {buyer_info}")
            print(f"销售方: {seller_info}")
            print(f"商品信息: {goods_info}")
            print(f"金额: {total_amount}")

            # 连接数据库
            conn = mysql.connector.connect(**DB_CONFIG)
            cursor = conn.cursor()
            
            # 获取图片数据
            image_path = self.images[0][0]
            with open(image_path, 'rb') as file:
                image_data = file.read()
            
            # 插入数据
            sql = """
                INSERT INTO invoices (
                    id, invoice_number, issue_date, image_data,
                    buyer_info, seller_info, goods_info, total_amount,
                    recognition_text
                ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
            """
            
            # 准备数据
            data = (
                image_uuid, 
                invoice_number, 
                mysql_date,  # 使用转换后的日期
                image_data,
                buyer_info, 
                seller_info, 
                goods_info, 
                total_amount,
                result_text
            )
            
            # 执行插入
            cursor.execute(sql, data)
            conn.commit()
            
            print("数据上传成功")
            messagebox.showinfo("成功", "数据已成功保存到数据库")
            self.result_window.destroy()
            
        except Error as e:
            error_msg = f"数据库错误: {str(e)}"
            print(error_msg)
            messagebox.showerror("数据库错误", error_msg)
        except Exception as e:
            error_msg = f"系统错误: {str(e)}"
            print(error_msg)
            messagebox.showerror("系统错误", error_msg)
        finally:
            if 'conn' in locals() and conn.is_connected():
                cursor.close()
                conn.close()

    def extract_info(self, text, keyword):
        """从识别结果中提取指定关键字后的信息"""
        lines = text.split('\n')
        result = []
        found = False
        
        for line in lines:
            if keyword in line:
                found = True
                # 提取冒号后的内容
                content = line.split('：')[-1].strip()
                if content:  # 如果当前行有内容
                    result.append(content)
            elif found and line.strip() and not any(k in line for k in ["发票编号", "开票日期", "购买方信息", "销售方信息", "商品名称", "金额合计"]):
                # 如果已经找到关键字，且当前行不是空行且不包含其他关键字，则添加到结果中
                result.append(line.strip())
            elif found and any(k in line for k in ["发票编号", "开票日期", "购买方信息", "销售方信息", "商品名称", "金额合计"]):
                # 如果遇到下一个关键字，则停止收集
                break
        
        return '\n'.join(result) if result else ""

    def go_back(self):
        self.prev_interface.show()
        self.master.destroy()


def init_database():
    """初始化数据库和表结构"""
    try:
        # 首先尝试连接MySQL服务器
        conn = mysql.connector.connect(
            host=DB_CONFIG['host'],
            user=DB_CONFIG['user'],
            password=DB_CONFIG['password']
        )
        cursor = conn.cursor()
        
        # 创建数据库（如果不存在）
        cursor.execute(f"CREATE DATABASE IF NOT EXISTS {DB_CONFIG['database']}")
        cursor.execute(f"USE {DB_CONFIG['database']}")
        
        # 检查表是否存在
        cursor.execute("SHOW TABLES LIKE 'invoices'")
        table_exists = cursor.fetchone()
        
        if not table_exists:
            # 如果表不存在，则创建表
            cursor.execute('''
                CREATE TABLE invoices (
                    id VARCHAR(36) PRIMARY KEY,
                    invoice_number VARCHAR(50),
                    issue_date VARCHAR(20),
                    image_data LONGBLOB,
                    buyer_info TEXT,
                    seller_info TEXT,
                    goods_info TEXT,
                    total_amount TEXT,
                    recognition_text TEXT,
                    created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            print("创建新表成功")
        else:
            print("表已存在，跳过创建")
        
        conn.commit()
        print("数据库初始化成功")
        return True
    except Error as e:
        print(f"数据库初始化失败: {str(e)}")
        messagebox.showerror("数据库错误", f"初始化失败: {str(e)}")
        return False
    finally:
        if 'conn' in locals() and conn.is_connected():
            cursor.close()
            conn.close()


if __name__ == "__main__":
    # 初始化数据库
    if not init_database():
        messagebox.showerror("错误", "数据库初始化失败，请检查数据库配置")
        exit(1)
    
    print("数据库配置：", DB_CONFIG)
    root = tk.Tk()
    main_interface = MainInterface(root)
    root.mainloop()